#include "cppTutorTCPSocketClient.h"

// log framework
#ifndef __CYGWIN__
#include "cppTutorLog.h"
extern CcppTutorLog Log;
#endif

// log framework
#include "cppTutorLog.h"
extern CcppTutorLog Log;

using namespace std;

CcppTutorTCPSocketClient :: CcppTutorTCPSocketClient () : iSin_size (0), iServerfd (0), iRet (0), iServerPort (0), iLogin (1), m_nReturnStatus (1), iOpenfd (0), iWriteNum (0)
{
	Log << "ENTER : CcppTutorTCPSocketClient :: CcppTutorTCPSocketClient ()" << endl;
    
	pLogin 	= "login  :";
	pPasswd = "passwd :";
	
    m_strIPAddress  = "192.168.22.64";
    m_strPort       = "9999";
    m_strClientLog  = "CcppTutorTCPSocketClient.log";
    
    Log << "EXIT  : CcppTutorTCPSocketClient :: CcppTutorTCPSocketClient ()" << endl;
}

CcppTutorTCPSocketClient :: CcppTutorTCPSocketClient (string strIPAddress, string strPort) : iSin_size (0), iServerfd (0), iRet (0), iServerPort (0), iLogin (1), m_nReturnStatus (1), iOpenfd (0), iWriteNum (0), m_strIPAddress (strIPAddress), m_strPort(strPort)
{   
    Log << "ENTER : CcppTutorTCPSocketClient :: CcppTutorTCPSocketClient ()" << endl;
    
	pLogin 	= "login  :";
	pPasswd = "passwd :";
	
    Log << "EXIT  : CcppTutorTCPSocketClient :: CcppTutorTCPSocketClient ()" << endl;
}

CcppTutorTCPSocketClient :: ~CcppTutorTCPSocketClient ()
{
	Log << "ENTER : CcppTutorTCPSocketClient :: ~CcppTutorTCPSocketClient ()" << endl;
	Log << "EXIT  : CcppTutorTCPSocketClient :: ~CcppTutorTCPSocketClient ()" << endl;
}

int CcppTutorTCPSocketClient :: ClientMain( ) 
{
	Log << "ENTER : CcppTutorTCPSocketClient :: ClientMain ()" << endl;

	if ( ( host = gethostbyname ( m_strIPAddress.c_str() ) ) == NULL )
	{
		Log << "CM : Gethostbyname Error !\n";
		exit ( 1 );
	}
	snprintf ( sServerIp , sizeof ( sServerIp ) , "%s" , m_strIPAddress.c_str() );
    Log << "CM : sServerIp = " << sServerIp << endl;
	iServerPort = atoi ( m_strPort.c_str() );
    Log << "CM : iServerPort = " << iServerPort << endl;
	snprintf ( pLogName , sizeof ( pLogName ) , "%s" , m_strClientLog.c_str() );
    Log << "CM : pLogName = " << pLogName << endl;
    
	iServerfd = socket ( AF_INET , SOCK_STREAM , 0 );
	if ( iServerfd == -1 )
	{
		Log << "CM : Socket Found error !\n";
		exit ( 1 );
	}
    else
    {	
        Log << "CM : Socket Found Success !\n";
    }
	server_addr.sin_family = AF_INET;
	server_addr.sin_port = htons ( iServerPort );
	server_addr.sin_addr.s_addr = inet_addr ( sServerIp );
	//server_addr.sin_addr.s_addr = htonl (* ( unsigned int * ) * host->h_addr_list );
	bzero ( & ( server_addr.sin_zero ) , 8 );

	while ( 1 ) 
	{
		iSin_size = sizeof ( server_addr );
		if ( connect ( iServerfd , ( struct sockaddr * ) &server_addr , iSin_size ) == -1 ) 
		{
			Log << "CM : Connect Error !\n";
			sleep ( 1 );
			continue;
		}
		printf ( "Connect IP : %s\nPort : %d\n" , sServerIp , iServerPort );

		while ( 1 )
		{
			iLogin = 1;
			while ( iLogin == 1 ) 
			{
				iRet = -1;
				while ( iRet == -1 || iRet == 0 ) 
				{
					memset ( sReceiveBuff , 0 , sizeof ( sReceiveBuff ) );
					iRet = recv ( iServerfd , sReceiveBuff , RECEIVE_BUFF_SIZE , 0 ); 
					if ( iRet == -1 ) 
					{
						Log << "CM : Receive Error !\n";
					}
				}
				strcpy ( sLogin , sReceiveBuff ) ;
				if ( strcmp ( pLogin , sLogin ) != 0 ) 
				{
					break;
				}
				else 
				{
					iRet = -1;
					//printf ( "%s" , sLogin );
					//scanf ( "%s" , &sKeyBoardInput );
					cout << sLogin;
					cin  >> sKeyBoardInput;
					while ( iRet == -1 ) 
					{
						iRet = send ( iServerfd , sKeyBoardInput , strlen( sKeyBoardInput ) , 0 );
						if ( iRet == -1 )
						{
							Log << "CM : Send Error !\n";
						}
					}

					iRet = -1;
					while ( iRet == -1 || iRet == 0 ) 
					{
						memset ( sReceiveBuff , 0 , sizeof ( sReceiveBuff ) );
						iRet = recv ( iServerfd , sReceiveBuff , RECEIVE_BUFF_SIZE , 0 ); 
						if ( iRet == -1 ) 
						{
							Log << "CM : Receive Error !\n";
						}
					}
					strcpy ( sPasswd , sReceiveBuff ) ;
					if ( strcmp ( pPasswd , sPasswd ) != 0 ) 
					{
						break;
					}
					else 
					{ 
						iRet = -1;
						//printf ( "%s" , sPasswd );
						//scanf ( "%s" , &sKeyBoardInput );
						cout << sPasswd;
						cin >> sKeyBoardInput;
						while ( iRet == -1 )
						{
							iRet = send ( iServerfd , sKeyBoardInput , strlen( sKeyBoardInput ) , 0 );
							if ( iRet == -1 ) 
							{
								Log << "CM : Send Error !\n";
							}
						}
					}
				}
				iRet = -1;
				while ( iRet == -1 || iRet == 0 ) 
				{
					memset ( sReceiveBuff , 0 , sizeof ( sReceiveBuff ) );
					iRet = recv ( iServerfd , sReceiveBuff , RECEIVE_BUFF_SIZE , 0 ); 
					if ( iRet == -1 ) 
					{
						Log << "CM : Receive Error !\n";
					}
				}
				if ( strcmp ( sReceiveBuff , "Login Failure !" ) == 0 ) 
				{
					Log << "CM : Login Failure\n";
					//printf ( "%s\n" , sReceiveBuff );
					cin >> sReceiveBuff;
				}
				else 
				{
					//printf ( "%s\n" , sReceiveBuff );
					cin >> sReceiveBuff;
					break;
				}
			}
			memset ( sPrintLogBuff , 0 , sizeof ( sPrintLogBuff ) );
			while ( 1 ) 
			{
				cout << "Client Message : " << endl;
				//scanf ( "%s" , &sKeyBoardInput ); 
				cin >> sKeyBoardInput; 
				//printf ( "KEY = %s\n" , sKeyBoardInput );
				snprintf ( sPrintLogBuff , sizeof ( sPrintLogBuff ) , "Client Message : %s\n" , sKeyBoardInput );
				iWriteLogClient ( pLogName , sPrintLogBuff );

				iRet = send ( iServerfd , sKeyBoardInput , strlen( sKeyBoardInput ) , 0 );
				if ( iRet == -1 ) 
				{
					Log << "CM : Send Error !\n";
				}

				memset ( sReceiveBuff , 0 , sizeof ( sReceiveBuff ) );
				iRet = recv ( iServerfd , sReceiveBuff , RECEIVE_BUFF_SIZE , 0 );	
				if ( iRet == -1 )
				{
					Log << "CM : Receive Error !\n";
				}
				else if ( iRet == 0 ) 
				{
					cout << "Server Closed !\n";
					close ( iServerfd );
					exit ( 1 );
				}
				else 
				{
					cout << "Server Message : \n"  << sReceiveBuff;
					memset ( sPrintLogBuff , 0 , sizeof ( sPrintLogBuff ) );
					snprintf ( sPrintLogBuff , sizeof ( sPrintLogBuff ) , "Server Message : %s\n" , sReceiveBuff );
					iWriteLogClient ( pLogName , sPrintLogBuff );
				}
			}
		}
	}
    Log << "EXIT : CcppTutorTCPSocketClient :: ClientMain () [" << m_nReturnStatus << " : " << __LINE__ << "]"<< endl;

	return m_nReturnStatus;
}

int CcppTutorTCPSocketClient :: iWriteLogClient (char * pFileName, char * pLogBuff)
{
	Log << "ENTER : CcppTutorTCPSocketClient :: iWriteLogClient()" << endl;

	iOpenfd = open ( pFileName , O_APPEND|O_RDWR|O_CREAT , S_IRWXU );
	iWriteNum = write (iOpenfd , pLogBuff , strlen ( pLogBuff ) );

	Log << "EXIT  : CcppTutorTCPSocketClient :: iWriteLogClient () [" << iWriteNum << " : " << __LINE__ << "]"<< endl;
	return iWriteNum;
}

// int main (int argc , char ** argv)
// {
    // CcppTutorTCPSocketClient tcpclient;
	// if ( argc < 2 )
	// {
		// printf ( "Usage : %s parameter\n" , argv[0] );
	// }
    // tcpclient.ClientMain (argc, argv);
    // return 0;
// };